/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 *
 */

import fs from 'fs';
import * as path from 'path';
import process from 'process';

import { HvigorLogger } from '../../base/log/hvigor-log';
import { PROJECT_CACHES, WORK_SPACE } from '../../common/const/const.js';
import { hash } from '@ohos/hvigor-common';
import { getHvigorUserHomeCacheDir } from '../../common/util/hvigor-user-home.js';
import { readProjectHvigorConfig } from '../../common/util/project-util';

import { DEFAULT_PROJECT_NODE_PATH } from './wrapper-const.js';

const _log = HvigorLogger.getLogger('prepare-node-path');

function adaptNode14Module(projectNodePath: string, hvigorConfigJson: any) {
  function tryToResolveDependency(request: string): string | undefined {
    if (!hvigorConfigJson.dependencies[request]) {
      return undefined;
    }
    const resolvedDir = path.resolve(projectNodePath, request);
    for (const suffix of ['.js', '.ts']) {
      const resolvedFile = path.resolve(resolvedDir, `index${suffix}`);
      if (fs.existsSync(resolvedFile)) {
        _log.debug(`adaptNode14Module, request = ${request}, resolvedFile = ${resolvedFile}`);
        return resolvedFile;
      }
    }
    return undefined;
  }

  const Module = require('module');
  const originalResolveFilename = Module._resolveFilename;
  Module._resolveFilename = (request: string, parent: any, isMain: boolean) => {
    try {
      return originalResolveFilename(request, parent, isMain);
    } catch (e) {
      return tryToResolveDependency(request) ?? originalResolveFilename(request, parent, isMain);
    }
  };
}

/**
 * 初始化编译构建
 *
 * @returns {string}
 */
export function initNodePath(hvigorProjectDependenciesHome?: string): string {
  const projectNodePath = hvigorProjectDependenciesHome
    ? path.resolve(hvigorProjectDependenciesHome, 'node_modules')
    : path.resolve(getHvigorUserHomeCacheDir(), PROJECT_CACHES, hash(process.cwd()), WORK_SPACE, 'node_modules');

  function concatNodePath() {
    if (DEFAULT_PROJECT_NODE_PATH) {
      return projectNodePath.concat(path.delimiter).concat(DEFAULT_PROJECT_NODE_PATH);
    } else {
      return projectNodePath;
    }
  }

  process.env.NODE_PATH = concatNodePath();

  _log.debug(`env: nodejsVersion=${process.version}`);
  const projectHvigorConfigJson = readProjectHvigorConfig();
  _log.debug('env: hvigor-config.json5 content =', projectHvigorConfigJson);
  if (process.version.startsWith('v14')) {
    // 适配流水线场景node14的bug，不是很完美，尽量推用户升级node到16或以上版本
    // 流水线场景执行./hvigorw clean --no-daemon会报错Cannot find module '@ohos/hvigor-ohos-plugin'
    // 安装完@ohos/hvigor-ohos-plugin后，会立刻去require hvigorfile从而require @ohos/hvigor-ohos-plugin, node14会报错
    adaptNode14Module(projectNodePath, projectHvigorConfigJson);
  }

  require('module').Module._initPaths();
  return projectNodePath;
}
